2023/12/231957字符
通道
非缓冲通道
- 无论是向通道中写入数据还是读取数据,都会发生阻塞。发送/读取结束后解除阻塞;
- 一次发送,一次接收,都是阻塞的(发送与接收次数不一致会发生死锁)。
package main
import "fmt"
func main() {
var ch chan bool
ch = make(chan bool)
go func() {
fmt.Print(1111111)
ch <- true // 向通道中写入数据
}()
data := <- ch // 从通道中读取数据
fmt.Println(data)
}
关闭通道
package main
import (
"fmt"
"time"
)
func main() {
ch := make(chan int)
go sendData(ch)
for v := range ch {
fmt.Print(v) //--> 01234
}
fmt.Println("end") //--> end
}
func sendData(ch chan int) {
for i := 0; i < 5; i++ {
time.Sleep(1 * time.Second)
ch <- i
}
close(ch) // 通知对方,关闭通道
}
缓冲通道
- 发送:缓冲区数据满了,才会发生阻塞;
- 接收:缓冲区数据为空,才会发生阻塞。
非缓冲通道 可以理解为是一个大小为 1 的缓冲通道
package main
import (
"fmt"
)
func main() {
ch := make(chan int, 2) // 缓冲通道,缓冲区大小为 2
go sendData(ch)
for {
v, ok := <-ch
if !ok { // 通道满了,退出循环
fmt.Println("readend")
break
}
fmt.Println("read:", v, "len:", len(ch))
}
fmt.Println(len(ch))
}
func sendData(ch chan int) {
for i := 1; i <= 5; i++ {
ch <- i
fmt.Println("write", i)
}
close(ch)
}
双向通道
var ch = make(chan int)
双向通道var ch = make(chan <- int)
单项通道:只能写,不能读var ch = make(<- chan int)
单项通道:只能读,不能写
package main
import (
"fmt"
)
func main() {
ch := make(chan int)
done := make(chan bool)
go sendData(ch, done)
num := <-ch
fmt.Println(num)
<-done // 等待协程结束
fmt.Println("end")
}
func sendData(ch chan int, done chan bool) {
ch <- 10
done <- true // 通知结束
}